﻿using System;
using CI.Interfaces;

namespace CI.Organism
{
    /// <summary>
    /// This is the learning rule associated with the synapse
    /// </summary>
    public interface ILearningRule
    {
        /// <summary>Learning rule GUID used to uniquely identify it in the neural system</summary>
        Guid Guid
        {
            get;
            set;
        }

        /// <summary>
        /// Notifiation that the target neuron has or hasnt fired and update
        /// </summary>
        /// <param name="fired">did or didnt it fire?</param>
        void TargetNeuronFired(bool fired);

        /// <summary>
        /// Learning rate of gain which makes the connections weight stronger
        /// </summary>
        double GainLearningRate
        {
            get;
        }

        /// <summary>
        /// Learning rate of loss which makes the connections weight weaker
        /// </summary>
        double LossLearningRate
        {
            get;
        }

        /// <summary>
        /// Take this learning rule and create a learning rule to be put in the new child Organism
        /// Mutate the current learning rule and return a new one, deep class level mutation
        /// </summary>
        /// <param name="mutationRate">mutation rate to be applied</param>
        /// <param name="childSynapse">child synapse it will be going into</param>
        /// <returns>new learning rule for child</returns>
        ILearningRule Mutate(double mutationRate, ISynapse childSynapse);

        /// <summary>
        /// do a equals comparison of one learning type to another only comparing the value types, no refference comparisons
        /// </summary>
        /// <param name="learningRule">learning rule to compare against</param>
        /// <returns>true if equal value types</returns>
        bool EqualsValueTypes(ILearningRule learningRule);
    }
}